﻿/*********************************************************************
 * @file       ticktimer.cpp
 * @brief      主滴答触发器
 * @details    每间隔一段时间就检查一次是否要触发闹钟或提醒
 * @author     南樟(a2169272059@163.com)
 * @date       2025-2-10
 * @version    1.0.0
 * @copyright  a2169272059@163.com
 *********************************************************************/
#include "ticktimer.h"
#include "dialog_timeout.h"
#include "sqlite.h"

#include <QMessageBox>
#include <QDate>
/// 数据库对象类
extern sqlite db;
/**
 * @brief tickTimer::tickTimer 主滴答触发器构造函数
 * @param parentWidget 所触发界面要挂载的父节点
 * @param parent 主滴答触发器的父节点
 */
tickTimer::tickTimer(QWidget *parentWidget,QObject *parent)
    : QObject{parent}
    ,m_parentWidget(parentWidget)
{
    m_clockQuery = nullptr;
    m_ticker = new QTimer(this);
    connect(m_ticker,&QTimer::timeout,this,&tickTimer::tickBell);
}
/**
 * @brief tickTimer::load_clock 闹钟表加载函数
 * @warning 加载时会停用滴答触发器，要用start()重新启动滴答触发器
 * @return 加载是否成功
 *  @retval true 加载成功
 *  @retval false 加载失败
 */
bool tickTimer::load_clock()
{
    m_ticker->stop();
    m_clockQuery = new QSqlQuery(db.get_db());
    m_clockQuery->prepare(
        "SELECT id,clock_time,bits_week "
        "FROM clock "
        "WHERE enable = 1 AND clock_time > :nowTime "
        "ORDER BY clock_time ASC"
    );
    m_clockQuery->bindValue(":nowTime",QTime::currentTime().toString("HH:mm"));
    if(!m_clockQuery->exec()){
        QMessageBox::warning(m_parentWidget,"错误","闹铃表更新错误");
        return false;
    }
    m_clockQuery->next();
    return true;
}
/**
 * @brief tickTimer::start 滴答触发器开始走表
 */
void tickTimer::start()
{
    m_ticker->start(6000);
}
/**
 * @brief tickTimer::tickBell 滴答触发器触发逻辑
 */
void tickTimer::tickBell()
{
    qDebug()<<"BELLing"<<getTimeStr(m_clockQuery);
    QString TimeStr = QTime::currentTime().toString("HH:mm");
    if(getTimeStr(m_clockQuery) == TimeStr){
        int tmp = getChackValue(m_clockQuery);
        if(tmp == 0 || tmp&(0x01<<QDate::currentDate().dayOfWeek())){
            dialog_timeout *dialog = new dialog_timeout(m_parentWidget);
            dialog->setAttribute(Qt::WA_DeleteOnClose); // 确保对话框关闭时自动释放内存
            dialog->activateWindow();
            dialog->raise();
            dialog->show();
            qDebug() << "bellOk";
        }
        m_clockQuery->next();
    }else if(TimeStr == "00:00"){
        load_clock();
    }
}
/**
 * @brief tickTimer::getTimeStr 得到闹钟表中当前的时间(string,"HH:mm")
 * @param query 查询得来的闹钟表
 * @return 闹钟表中当前的时间(string,"HH:mm")
 */
inline QString tickTimer::getTimeStr(QSqlQuery *query)
{
    return query->value(1).toString();
}
/**
 * @brief tickTimer::getChackValue 得到闹钟表中的触发星期数据
 * @param query 查询得来的闹钟表
 * @return 一个int,将其转化为二进制后进行bits运算后使用
 * @note 二进制0100100代表该闹钟在周三和周6触发
 */
inline int tickTimer::getChackValue(QSqlQuery *query)
{
    return query->value(2).toInt();
}
/**
 * @brief tickTimer::getId 得到闹钟表中该数据的对应id
 * @param query 查询得来的闹钟表
 * @return 该数据在数据库中的对应id
 */
inline int tickTimer::getId(QSqlQuery *query)
{
    return query->value(0).toInt();
}

